﻿package com.pool.core 
{
	import com.pool.Config;
	import flash.display.DisplayObject;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.Sound;
	import flash.utils.Dictionary;
	import org.dm.display.DisplayMgr;
	
	import com.pool.events.GameEvent;
	import org.dm.math.geom.Num2;
	
	import flash.ui.Mouse;
	
	/**
	 * ...
	 * @author Scott
	 */
	public class PoolGame extends EventDispatcher
	{
		private var _balls:Balls;
		
		private var _cue:Sprite;
		private var _errorHand:Sprite;
		private var _moveHand:Sprite;
		private var _aimHand:Sprite;
		private var _ready:SimpleButton;
		private var _readyLight:Sprite;
		private var _readyDark:Sprite;
		private var _helpLine:Sprite;
		private var _powerMark:Sprite;
		private var _powerLen:Sprite;
		private var _returnBtn:SimpleButton;
		
		private var _hitSound:Sound;
		private var _collideSound:Sound;
		
		private var _gameArea:Rectangle;
		private var _holes:Array;
		
		private var mouseDown:Boolean = false;
		private var mouseUp:Boolean = false;
		
		private var _display:Sprite
		private var _isFirstDown:Boolean = true;  //鼠标第一次的按下
		private var _mousePoint:Point;
		private var r:Number=12.5
		
		public function PoolGame()
		{
			super();
			_display = DisplayMgr.getDisplay("game.bg", "win.GameWin");
			
			_hitSound = DisplayMgr.getDisplay("game.hitsound","sound.Hit");
			_collideSound = DisplayMgr.getDisplay("game.collidesound","sound.Collide");
			_cue = DisplayMgr.getDisplay("game.cue","btn.Cue");
			_errorHand = DisplayMgr.getDisplay("game.errorHand","btn.ErrorHand");
			_moveHand = DisplayMgr.getDisplay("game.moveHand","btn.MoveHand");
			_aimHand = DisplayMgr.getDisplay("game.aimHand", "btn.AimHand");
			
			_ready = _display.getChildByName("gameReady") as SimpleButton;
			_readyLight = _display.getChildByName("readyLight") as Sprite;
			_readyDark = _display.getChildByName("readyDark") as Sprite;
			
			_returnBtn = DisplayMgr.getDisplay("game.return", "btn.ReturnBtn");
			_returnBtn.x = _display.width - 30;
			_returnBtn.y = 5;
			_display.addChild(_returnBtn);
			//_powerMark = _display.getChildByName("powerMark") as Sprite;
			//_powerLen = (_powerMark.getChildAt(0) as Sprite).getChildByName("mask") as Sprite;
		}
		
		private function init():void 
		{			
			removeE(_cue);
			removeE(_errorHand);
			removeE(_aimHand);
			removeE(_moveHand);
			removeE(_readyLight);
			removeE(_powerMark);
			
			_gameArea = new Rectangle(41,43,717,356);			
			Config.deskW = _gameArea.width;
			Config.deskH = _gameArea.height;
			Config.deskCenter = new Point(_gameArea.width / 2, _gameArea.height / 2);
			_balls = new Balls(16);
			_balls.x = _gameArea.x;
			_balls.y = _gameArea.y;
			_helpLine = new Sprite();
			_mousePoint = new Point();
			
			_display.addChild(_balls);
			_ready.addEventListener(MouseEvent.CLICK, onReady);
			_ready.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
			_ready.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);	
		}
		
		public function start():void 
		{
			Config.status = 1;  //等待准备
			Config.mouseStatus = 0;
			_display.addEventListener(Event.ENTER_FRAME, run);
			_balls.addEventListener(GameEvent.STOPALL, onStopAll);
		}
		
		public function stop():void
		{
			Config.status = 0;
			Config.mouseStatus = 0;
			_display.removeEventListener(Event.ENTER_FRAME, run);			
		}
		
		//游戏的逻辑
		public function run(e:Event):void 
		{
			switch (Config.status) 
			{
				case 0:		//用于跳过状态检测
					break;
				case 1:		//未准备状态
					switch (Config.mouseStatus) 
					{
						case 0:
							break;
						case 1:			//鼠标移上时，添加准备按钮的高光
							Config.mouseStatus = 0;
							addE(_readyLight, _display.numChildren - 2);
							break;
						case 4:			//鼠标移开时，移除准备按钮的高光
							Config.mouseStatus = 0;
							removeE(_readyLight);
							break;
					}
					break;
				case 2:		//击球
					switch (Config.mouseStatus) 
					{
						case 0:		//击球前鼠标移动
							onReadyShot();
							break;
						case 2:		//按下击球，蓄力
							onReadyShot();
							addPower();
							break;
						case 3:		//放开鼠标，击球
							_balls.angle =Math.atan2(_aimHand.y - _cue.y, _aimHand.x - _cue.x);
							_balls.onShot();
							Config.status = 3;
							Config.mouseStatus = 10;
							_display.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
							_display.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);	
							Mouse.show();
							removeE(_cue);
							removeE(_aimHand);
							removeE(_helpLine);
							removeE(_powerMark);
							_powerLen.width = 80;
							_hitSound.play();
							break;
						case 10:	//初始化击球
							if (!_balls.whiteBall.isOn)
							{
								Config.status = 4;
								break;
							}
							Config.mouseStatus = 0;							
							_cue.x = _balls.whiteBall.px + _gameArea.x;
							_cue.y = _balls.whiteBall.py + _gameArea.y;							
							_aimHand.x = _display.mouseX;
							_aimHand.y = _display.mouseY;
							Mouse.hide();							
							addE(_helpLine);
							addE(_cue);
							addE(_aimHand);
							_display.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
							_isFirstDown = true;
							break;
					}
					break;
				case 3:		//击球后，碰撞检测及碰撞
					switch (Config.mouseStatus) 
					{
						case 0:		//
							break;
						case 10:
							Config.mouseStatus = 0;
							_balls.addEventListener(GameEvent.HIT, onHit);							
							_balls.render();
							break;
					}
					break;
				case 4:		//放球
					switch(Config.mouseStatus)
					{
						case 0:
							onMoveBall();
							break;
						case 2:		//放球
							if (!_balls.isCanBall())
							{
								Config.mouseStatus = 0;
								break;
							}
							Config.status = 2;
							Config.mouseStatus = 10;
							removeE(_moveHand);
							removeE(_errorHand);
							_balls.whiteBall.isOn = true;
							_display.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
							Mouse.show();
							break;
						case 10:
							Config.mouseStatus = 0;
							_moveHand.x = _display.mouseX;
							_moveHand.y = _display.mouseY;
							_balls.whiteBall.px = _display.mouseX-_gameArea.x;
							_balls.whiteBall.py = _display.mouseY - _gameArea.y;
							_balls.whiteBall.reDraw();
							_balls.whiteBall.visible = true;
							//addE(_moveHand);
							Mouse.hide();
							_display.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
							break;
					}
					break;
				default:
					break;
			}
		}
		
		public function onHit(e:GameEvent):void 
		{
			_collideSound.play();
		}
		
		public function get display():Sprite
		{
			return this._display; 
		}
		
		public function onMoveBall():void 
		{
			_mousePoint.x = _display.mouseX;
			_mousePoint.y = _display.mouseY;
			if (_display.mouseX < _gameArea.x+r)
			{
				_mousePoint.x = _gameArea.x+r;
			}
			else if (_display.mouseX > _gameArea.x + _gameArea.width-r)
			{
				_mousePoint.x = _gameArea.x + _gameArea.width-r;
			}
			if (_display.mouseY < _gameArea.y+r)
			{
				_mousePoint.y = _gameArea.y+r;
			}
			else if (_display.mouseY > _gameArea.y + _gameArea.height-r)
			{
				_mousePoint.y = _gameArea.y + _gameArea.height-r;
			}
			
			if(_balls.isCanBall())
			{
				_moveHand.x = _mousePoint.x;
				_moveHand.y = _mousePoint.y;
				removeE(_errorHand);
				addE(_moveHand);
			}
			else
			{
				_errorHand.x = _mousePoint.x;
				_errorHand.y = _mousePoint.y;
				removeE(_moveHand);
				addE(_errorHand);
			}
			
			_balls.whiteBall.px = _mousePoint.x-_gameArea.x;
			_balls.whiteBall.py = _mousePoint.y - _gameArea.y;
			_balls.whiteBall.reDraw();
			
			
		}
		
		public function onStopAll(e:GameEvent):void 
		{			
			_balls.stop();
			_balls.power = 0;
			_balls.angle = 0;
			_balls.removeEventListener(GameEvent.HIT, onHit);
			Config.mouseStatus = 10;
			//Config.status = 2;
			if (!_balls.whiteBall.isOn)
			{
				Config.status = 4;
			}
			else
			{
				Config.status = 2;
			}
		}
		
		public function onReady(e:MouseEvent):void 
		{
			removeE(_ready);
			removeE(_readyLight);
			removeE(_readyDark);
			_balls.reSet();
			_ready.removeEventListener(MouseEvent.CLICK, onReady);
			_ready.removeEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
			_ready.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
			
			_balls.addEventListener(GameEvent.STOPALL, onIsStop);
			Config.status = 2;	//切换为正常练习
			Config.mouseStatus = 10;
		}
		
		public function drawLine(startX:Number,startY:Number,stopX:Number,stopY:Number):void 
		{
			_helpLine.graphics.clear();
			_helpLine.graphics.lineStyle(1, 0xFFFFFF);
			_helpLine.graphics.moveTo(startX, startY);
			_helpLine.graphics.lineTo(stopX, stopY);
		}
		
		public function onIsStop(e:GameEvent):void 
		{
			Config.status = 2;
			Config.mouseStatus = 10;
			_balls.stop();
		}
		
		public function reSetGame():void 
		{
			_balls.reSet();
		}
		
		public function reSet():void 
		{
			
		}
		
		public function addPower():void 
		{
			if (_isFirstDown) 
			{
				_isFirstDown = false;
				_display.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
				addE(_powerMark);
			}
			_balls.power += Config.powerSpeed;			
			if (_balls.power > 20||_balls.power < 0) Config.powerSpeed = -Config.powerSpeed;
			_balls.power = _balls.power < 0? -_balls.power:_balls.power;
			_powerLen.width = _balls.power * 4;
		}
		
		public function onMouseOver(e:MouseEvent):void 
		{
			Config.mouseStatus = 1;
		}
		
		public function onMouseDown(e:MouseEvent):void 
		{
			Config.mouseStatus = 2;
		}
		
		public function onMouseUp(e:MouseEvent):void 
		{
			Config.mouseStatus = 3;
		}
		
		public function onMouseOut(e:MouseEvent):void 
		{
			Config.mouseStatus = 4;
		}
		
		public function onMouseMove(e:MouseEvent):void 
		{
			Config.mouseStatus = 5;
		}
		
		public function onReadyShot():void 
		{
			_aimHand.x = _display.mouseX;
			_aimHand.y = _display.mouseY;
			
			_powerMark.x = _display.mouseX;
			_powerMark.y = _display.mouseY;
			
			var angle:Number=-Num2.RADTODEG*Math.atan2(_display.mouseX - _balls.whiteBall.px-_gameArea.x, _display.mouseY - _balls.whiteBall.py-_gameArea.y);
			_cue.rotation = angle;
			
			drawLine(_cue.x, _cue.y, _aimHand.x, _aimHand.y);
		}
		
		public function addE(sp:DisplayObject,level:int=0):void 
		{
			if (level >0)
			{
				if (!_display.contains(sp)) _display.addChildAt(sp,level);
			}
			else
			{
				if (!_display.contains(sp)) _display.addChild(sp);
			}
		}
		
		public function removeE(sp:DisplayObject):void 
		{
			if (_display.contains(sp)) _display.removeChild(sp);
		}
	}
}